<?php

declare(strict_types=1);

namespace App\Fastapp\Model;

use Hyperf\Database\Model\Relations\HasMany;
use Hyperf\Database\Model\Relations\HasOne;
use Hyperf\Database\Model\SoftDeletes;
use Mine\MineModel;

/**
 * @property int $id 用户ID，主键
 * @property \Carbon\Carbon $created_at 创建时间
 * @property \Carbon\Carbon $updated_at 更新时间
 * @property string $deleted_at 删除时间
 * @property string $username 用户名
 * @property string $code 手机区号
 * @property string $mobile 手机
 * @property string $email 用户邮箱
 * @property int $status 状态 (1正常 2停用)
 * @property string $last_ip 最后登陆IP
 * @property string $last_at 最后登陆时间
 * @property int $type 入口类型 常规<500000 700001游戏 800001交易所
 * @property int $no 用户编号
 * @property int $gene_id uid
 * @property string $invite_code 邀请码
 * @property int $channel
 * @property string $password 密码
 * @property-read null|AccountInfo $info
 * @property-read null|AccountRealname $realname
 * @property-read null|AccountRecharge $recharge
 * @property-read null|AccountWithdrawal $withdrawal
 * @property-read null|AccountWalletLog $transaction
 * @property-read null|AccountWalletLog $profit
 * @property-read null|AccountSetting $settingPassword
 * @property-read null|AccountSetting $settingWithdrawalRechargeRate
 * @property-read null|AccountInviteLevel $parent
 * @property-read null|\Hyperf\Database\Model\Collection|AccountInviteLevel[] $childrenNum
 */
class Account extends MineModel
{
    use SoftDeletes;

    /**
     * The table associated with the model.
     */
    protected ?string $table = 'account';

    /**
     * The attributes that are mass assignable.
     */
    protected array $fillable = ['id', 'created_at', 'updated_at', 'deleted_at', 'username', 'code', 'mobile', 'email', 'password', 'status', 'last_ip', 'last_at', 'type', 'no', 'gene_id', 'invite_code', 'channel'];

    /**
     * The attributes that should be cast to native types.
     */
    protected array $casts = ['id' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime', 'status' => 'integer', 'type' => 'integer', 'no' => 'integer', 'gene_id' => 'integer', 'channel' => 'integer'];

    protected array $hidden = ['password'];

    public function setPasswordAttribute(string $value): void
    {
        $this->attributes['password'] = password_hash($value, PASSWORD_DEFAULT);
    }

    public static function passwordVerify(string $password, string $hash): bool
    {
        return password_verify($password, $hash);
    }

    public function info(): HasOne
    {
        return $this->hasOne(AccountInfo::class, 'user_id', 'gene_id');
    }

    public function realname(): HasOne
    {
        return $this->hasOne(AccountRealname::class, 'user_id', 'gene_id')->where(['type' => 1]);
    }

    public function recharge(): HasOne
    {
        return $this->hasOne(AccountRecharge::class, 'user_id', 'gene_id')
            ->where(['status' => 1])
            ->selectRaw('user_id,sum(amount) as amount')->groupBy('user_id')->withDefault();
    }

    public function withdrawal(): HasOne
    {
        return $this->hasOne(AccountWithdrawal::class, 'user_id', 'gene_id')
            ->whereIn('status', [0, 1])
            ->selectRaw('user_id,sum(amount) as amount')->groupBy('user_id')->withDefault();
    }

    public function transaction(): HasOne
    {
        return $this->hasOne(AccountWalletLog::class, 'user_id', 'gene_id')
            ->selectRaw('SUM(amount) as amount,user_id,currency_id')
            ->where(['type' => AccountWalletLog::USE_BALANCE, 'field' => 'balance'])
            ->groupBy(['user_id', 'currency_id'])->withDefault();
    }

    public function profit(): HasOne
    {
        return $this->hasOne(AccountWalletLog::class, 'user_id', 'gene_id')
            ->selectRaw('SUM(amount) as amount,user_id,currency_id')
            ->where(['type' => AccountWalletLog::RECHARGE, 'field' => 'balance'])
            ->whereIn('object_type', [71, 3, 4, 6])
            ->groupBy(['user_id', 'currency_id'])->withDefault();
    }

    public function settingPassword(): HasOne
    {
        return $this->hasOne(AccountSetting::class, 'user_id', 'gene_id')->where(['key' => 'password'])->withDefault();
    }

    public function settingWithdrawalRechargeRate(): HasOne
    {
        return $this->hasOne(AccountSetting::class, 'user_id', 'gene_id')->where(['key' => 'withdrawal_recharge_rate']);
    }

    public function parent(): HasOne
    {
        return $this->hasOne(AccountInviteLevel::class, 'user_id', 'gene_id');
    }

    public function childrenNum(): HasMany
    {
        return $this->hasMany(AccountInviteLevel::class, 'parent_id', 'gene_id');
    }
}
